在我們的第一個 flutter 專案中,會發現有兩個 class 分別繼承 StatefulWidget 與 StatelessWidge,
顧名思義就是「無狀態」的 Widget,像是 Icon / Button / Text 等是屬於無狀態的 Widget,如果今天我們只是要做一個靜態的頁面,這邊來個實際範例,下方的頁面我們只需要圖片、標題、與內文,這時候我們使用 StatelessWidget 就可以做出我們想要的畫面
從下方 main.dart
程式碼可以發現,只使用了靜態的 Widget 去做排版,所有的內容都是最後的值,不會再改變。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'UI Demo',
home: Scaffold(
body: ListView(
children: [
Image.asset(
'images/highway.jpg',
width: 600,
height: 240,
fit: BoxFit.cover,
),
Center(
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Text(
'HighWay',
style: TextStyle(
color: Colors.blueGrey.shade900,
fontSize: 24,
fontWeight: FontWeight.bold),
),
),
),
const Padding(
padding: EdgeInsets.all(20),
child: Text(
'A highway is any public or private road or other public way on land. It is used for major roads, but also includes other public roads and public tracks. In some areas of the United States, it is used as an equivalent term to controlled-access highway, or a translation for autobahn, autoroute, etc.'),
)
],
)),
);
}
}
但 APP 一定不可能沒有所謂的互動或畫面上的更新,這時候該怎麼處理呢?
就交給具備 State(狀態)的
使用 StatefulWidget 可以讓 APP 的內容被重新渲染並在生命週期內利用 setState()
來更新狀態,像是 Radio / Slide / Form 等是屬於有狀態的 Widget,利用上方的範例示範一下,目前一張圖片有點枯燥,假設我們想要點擊圖片時,可以隨機更換不同 highway 的圖片
首先我們要先建立 StatefulWidget 和 State,在 VSCode 中你可以打 stf 就會出現建立 StatefulWidget 的選項,點下去後就會幫我們無痛(無腦)建立好兩個 class
接著把我們的 Widget 名稱修改一下,這邊先叫做 RoadWidget
好了,而 State 就改為
_RoadWidgetState
並且先把剛剛 Stateless Widget 中的架構先原封不動搬進來
// main.dart 檔案
import 'package:flutter/material.dart';
void main() {
runApp(const RoadWidget()); // 別忘了這邊要改成執行 RoadWidget
}
class RoadWidget extends StatefulWidget {
const RoadWidget({Key? key}) : super(key: key);
@override
State<RoadWidget> createState() => _RoadWidgetState();
}
class _RoadWidgetState extends State<RoadWidget> {
@override
Widget build(BuildContext context) {
return MaterialApp(
// 省略
);
}
}
接著利用 TextButton
的 Widget 來處理讓圖片可以點擊,Button 的 widget 提供一個屬性 onPressed
用來定義點擊需要執行的邏輯
將原本的 Image 組件外層再新增 TextButton 組件
TextButton(
onPressed: _randomImg,
child: Image.asset(
'images/highway$highwayNum.jpg',
width: 600,
height: 240,
fit: BoxFit.cover,
),
),
可以看到 onPressed
中執行了 _randomImg
函式,另外還有一個重點地方就是圖片的路徑名稱,我使用了一個變數 highwayNum
,如此一來我們就可以利用改變這個變數來讀取不同張圖片,達到我們想要的效果
// 宣告初始化的圖片編號
int highwayNum = 1;
void _randomImg() {
// setState 改變狀態
setState(() {
// 這邊我們有使用 dart:math 的 library 來產生隨機數字
highwayNum = Random().nextInt(4) + 1;
});
}
重新執行後來看看結果吧~點擊後順利的隨機更換圖片了!
希望透過範例大家能更了解無狀態與有狀態 widget 的分別~
OK!我們明天見~